#include "herm/base/utils/misc.h"
//#include "herm/base/socket.h"
#include "udp_session.h"
#include "udp_session_mgr.h"

UDPSessionMgr::UDPSessionMgr(UDPPeer* peer, const herm::PeerParam& peerParam)
{
//	m_addrSessions = new AddrSessions(peerParam.sessionCount);
	m_udpSessionObjMgr = new UDPSessionObjMgr(peerParam.sessionCount);
	for (int i = 0; i < peerParam.sessionCount; i++)
		m_udpSessionObjMgr->GetObj(i)->Init(peer, i);
}

UDPSessionMgr::~UDPSessionMgr()
{
//	m_addrSessions->Clear();
//	HERM_DELETE(m_addrSessions);
	HERM_DELETE(m_udpSessionObjMgr);
}

UDPSession* UDPSessionMgr::Create(const herm::Address& addr)
{
	// Find a existed session or acquire a session in the session obj mgr.
	AddrPair addrPair(addr.NetIP(), addr.NetPort());
//	const herm::uint32_t* sessionIdx = m_addrSessions->Find(addrPair);
//	if (sessionIdx)
//		return m_udpSessionObjMgr->GetObj(*sessionIdx);

	unsigned int idx = m_udpSessionObjMgr->Acquire();
	UDPSession* session = m_udpSessionObjMgr->GetObj(idx);
	if (session)
	{
//		m_addrSessions->Insert(addrPair, idx);
		session->Reset(addr);
	}

	return session;
}

UDPSession* UDPSessionMgr::Get(const herm::Address& addr)
{
//	const herm::uint32_t* idx = m_addrSessions->Find(std::make_pair(addr.NetIP(), addr.NetPort()));
//	if (!idx)
		return nullptr;
	
//	return m_udpSessionObjMgr->GetObj(*idx);
}

bool UDPSessionMgr::Destroy(herm::ISession* session)
{
	if (!session)
		return false;

	UDPSession* udpSession = dynamic_cast<UDPSession*>(session);
	if (!udpSession)
		return false;

	// Release from object manager
	m_udpSessionObjMgr->Release(session->GetIndex());

	// Erase from Addr->Index hashtable.
	herm::Address addr = udpSession->GetRemoteAddr();
	return true;
//	return m_addrSessions->Erase(std::make_pair(addr.NetIP(), addr.NetPort()));
}

UDPSessionObjMgr* UDPSessionMgr::GetSessions() const
{
	return m_udpSessionObjMgr;
}
